from typing import Optional

from appium import webdriver
from appium.options.common import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
from loguru import logger
from selenium.common import StaleElementReferenceException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

from basic.base_driver import DRIVER


class BasePage:
    def __init__(self):
        self.driver = DRIVER

    def _locator(self, loc, wait: int = None, freq: int = 0.5) -> Optional['webElement']:
            # 定位元素
            # :param loc: 元素定位表达式，格式为(appiumBy.XPATH, "xpath表达式")
            # :param wait: 等待时间，默认None
            # :param freq: 等待频率，默认0.5秒
            # :return: 定位到的元素，未找到则返回None
        return self.driver.find_element(*loc) if wait is None else\
            WebDriverWait(self.driver, wait, freq,[StaleElementReferenceException]).until(
                lambda x: x.find_element(*loc))

    def _click(self, loc, wait: int = None, freq: int = 0.5):
        if isinstance(loc, str):
            loc = (AppiumBy.ANDROID_UIAUTOMATOR, loc)
        else:
            loc = (AppiumBy.XPATH, loc)
        logger.info(f"点击元素{loc}")
        self._locator(loc, wait).click()

    def current_page(self):
        return self.driver.current_activity

    def _get_phone_size(self):
        """
        获取手机屏幕尺寸
        :return: 手机屏幕尺寸，格式为(width, height)
        """
        width = self.driver.get_window_size()['width']
        height = self.driver.get_window_size()['height']
        return width, height

    def _swipe_up(self, duration: int = 500, csy=0.8, cey=0.2):
        """
        上滑操作
        :param duration: 滑动持续时间，默认500毫秒
        :param csy: 起始点纵坐标比例，默认0.8
        :param cey: 终点纵坐标比例，默认0.2
        :return: None
        """
        width, height = self._get_phone_size()
        start_x = width * 0.5
        start_y = height * csy
        end_x = width * 0.5
        end_y = height * cey
        return self.driver.swipe(start_x, start_y, end_x, end_y, duration)


    def _swipe_down(self, duration: int = 500, csy=0.8, cey=0.2):
        """
        下滑操作
        :param duration: 滑动持续时间，默认500毫秒
        :param csy: 起始点纵坐标比例，默认0.8
        :param cey: 终点纵坐标比例，默认0.2
        :return: None
        """
        width, height = self._get_phone_size()
        start_x = width * 0.5
        start_y = height * csy
        end_x = width * 0.5
        end_y = height * cey
        return self.driver.swipe(start_x, start_y, end_x, end_y, duration)


    def _swipe_left(self, duration: int = 500):
        """
        左滑操作
        :param duration: 滑动持续时间，默认500毫秒
        :return: None
        """
        width, height = self._get_phone_size()
        start_x = width * 0.1
        start_y = height * 0.5
        end_x = width * 0.9
        end_y = height * 0.5
        return self.driver.swipe(start_x, start_y, end_x, end_y, duration)


    def _swipe_right(self, duration: int = 500):
        """
        右滑操作
        :param duration: 滑动持续时间，默认500毫秒
        :return: None
        """
        width, height = self._get_phone_size()
        start_x = width * 0.9
        start_y = height * 0.5
        end_x = width * 0.1
        end_y = height * 0.5
        return self.driver.swipe(start_x, start_y, end_x, end_y, duration)
